﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Resources;

namespace Chromatics
{
    /// <summary>
    /// Enum of diffrent level complexities(easy, meium,hard)
    /// </summary>
    public enum Difficulty {Easy, Medium, Hard};

    public struct PalleteColors 
    {
        public static Color Default
        {
            get
            {
                return new Color() { A = 0xFF, R = 0xD4, G = 0xD2, B = 0xCD };
            }
        }

        public static Color Red
        {
            get
            {
                return new Color() { A = 0xFF, R = 0xFF, G = 0x00, B = 0x1D };
            }
        }

        public static Color DarkRed
        {
            get
            {
                return new Color() { A = 0xFF, R = 0xD9, G = 0x15, B = 0x15 };
            }
        }

        public static Color Green
        {
            get
            {
                return new Color() { A = 0xFF, R = 0x42, G = 0xE0, B = 0x13 };
            }
        }

        public static Color DarkGreen
        {
            get
            {
                return new Color() { A = 0xFF, R = 0x45, G = 0xBC, B = 0x21 };
            }
        }

        public static Color Yellow
        {
            get
            {
                return new Color() { A = 0xFF, R = 0xD7, G = 0xE0, B = 0x13 };
            }
        }

        public static Color DarkYellow
        {
            get
            {
                return new Color() { A = 0xFF, R = 0xCD, G = 0xD2, B = 0x2B };
            }
        }

        public static Color Blue
        {
            get
            {
                return new Color() { A = 0xFF, R = 0x37, G = 0x37, B = 0xB9 };
            }
        }

        public static Color DarkBlue
        {
            get
            {
                return new Color() { A = 0xFF, R = 0x31, G = 0x31, B = 0x8E };
            }
        }

        public static Color Azure
        {
            get
            {
                return new Color() { A = 0xFF, R = 0x00, G = 0xD1, B = 0xFF };
            }
        }

        public static Color DarkAzure
        {
            get
            {
                return new Color() { A = 0xFF, R = 0x18, G = 0xAE, B = 0xD4 };
            }
        }

        public static Color Orange
        {
            get
            {
                return new Color() { A = 0xFF, R = 0xFF, G = 0x97, B = 0x00 };
            }
        }

        public static Color DarkOrange
        {
            get
            {
                return new Color() { A = 0xFF, R = 0xEC, G = 0x9B, B = 0x21 };
            }
        }
    }

    public class StrToEnumConverter
    {
        public static Difficulty strToDiff(string str)
        {
            Difficulty toRet;
            switch (str)
            {
                case "Easy":
                    toRet = Difficulty.Easy;
                    break;
                case "Medium":
                    toRet = Difficulty.Medium;
                    break;
                case "Hard":
                    toRet = Difficulty.Hard;
                    break;
                default:
                    throw new NullReferenceException("Unavaliable difficulty");
            }
            return toRet;
        }

        public static LevelStatus strToStat(string str)
        {
            LevelStatus status;
            switch (str)
            {
                case "Open":
                    status = LevelStatus.Open;
                    break;
                case "Closed":
                    status = LevelStatus.Closed;
                    break;
                case "Star0":
                    status = LevelStatus.Star0;
                    break;
                case "Star1":
                    status = LevelStatus.Star1;
                    break;
                case "Star2":
                    status = LevelStatus.Star2;
                    break;
                case "Star3":
                    status = LevelStatus.Star3;
                    break;
                default:
                    status = LevelStatus.Closed;
                    break;
            }
            return status;
        } 
    }

    /// <summary>
    /// Class to store user settings
    /// </summary>
    public class UserSettings
    {
        public bool Sound { get; set; }
        public bool Music { get; set; }
    }

    public class Level
    {
        public int Number { get; set; }
        public Difficulty Difficulty { get; set; }
        public LevelStatus Status { get; set; }
    }

    public enum LevelStatus { Open, Closed, Star0, Star1, Star2, Star3};
    public enum LevelState { Accepted, Error, Ok};
    public struct TileStatus
    {
        public static string Open
        {
            get
            {
                return "";
            }
        }

        public static string Locked
        {
            get
            {
                return "/Resources/SilverLock.png";
            }
        }

        public static string Passed
        {
            get
            {
                return "/Resources/BronzeTick.png";
            }
        }

        public static string OneStar
        {
            get
            {
                return "/Resources/GoldStar1.png";
            }
        }

        public static string TwoStars
        {
            get
            {
                return "/Resources/GoldStar2.png";
            }
        }

        public static string ThreeStars
        {
            get
            {
                return "/Resources/GoldStar3.png";
            }
        }
    }

    public class SoundPlayer
    {
        private static Microsoft.Xna.Framework.Audio.SoundEffectInstance instance = null;
        private static bool isPlaying = false;

        public static void PlayDing()
        {
            if (DataLoader.Instance.LoadUserSettings().Sound == true)
            {
                Microsoft.Xna.Framework.FrameworkDispatcher.Update();
                StreamResourceInfo info = App.GetResourceStream(new Uri("Resources/ding.wav", UriKind.Relative));
                Microsoft.Xna.Framework.Audio.SoundEffect soundEf = Microsoft.Xna.Framework.Audio.SoundEffect.FromStream(info.Stream);
                soundEf.Play();
            }
        }

        public static void PlayDrop()
        {
            if (DataLoader.Instance.LoadUserSettings().Sound == true)
            {
                Microsoft.Xna.Framework.FrameworkDispatcher.Update();
                StreamResourceInfo info = App.GetResourceStream(new Uri("Resources/drop.wav", UriKind.Relative));
                Microsoft.Xna.Framework.Audio.SoundEffect soundEf = Microsoft.Xna.Framework.Audio.SoundEffect.FromStream(info.Stream);
                soundEf.Play();
            }
        }

        public static void PlayLock()
        {
            if (DataLoader.Instance.LoadUserSettings().Sound == true)
            {
                Microsoft.Xna.Framework.FrameworkDispatcher.Update();
                StreamResourceInfo info = App.GetResourceStream(new Uri("Resources/Lock.wav", UriKind.Relative));
                Microsoft.Xna.Framework.Audio.SoundEffect soundEf = Microsoft.Xna.Framework.Audio.SoundEffect.FromStream(info.Stream);
                soundEf.Play();
            }
        }

        public static void StartErrorSound()
        {
            if (instance == null)
            {
                Microsoft.Xna.Framework.FrameworkDispatcher.Update();
                StreamResourceInfo info = App.GetResourceStream(new Uri("Resources/Lock.wav", UriKind.Relative));
                Microsoft.Xna.Framework.Audio.SoundEffect soundEf = Microsoft.Xna.Framework.Audio.SoundEffect.FromStream(info.Stream);
                instance = soundEf.CreateInstance();
                instance.IsLooped = true;
            }
            if (!isPlaying && DataLoader.Instance.LoadUserSettings().Sound == true)
            {
                instance.Play();
                isPlaying = true;
            }

        }

        public static void StopErrorSound()
        {
            if (instance != null)
            {
                instance.Pause();
                isPlaying = false;
            }
        }
    }
}
